#  This script is to do a mass rename of files/directories, and their contents.
#  An example scenario where this may apply is changing project code-names to the
#  real project name.  Or wanting to change namespaces mid-stream.
#
#  The rename method does the actual renaming, so if you don't want it to use SVN,
#  you can change that logic there.
#
#  Good luck.

require "fileutils"

# the directories to replace the name over
DIRS = ["src"]

# list of file extensions that will not be modified during file content replacement
# this is typically a list of binary files that you should not string process
NO_REPLACE_EXTS = ["dll", "pdb", "sdf", "ico"]

# map of replacement strings.  this applies to file names, and file contents
RENAMES = {
  "Original" => "New"}

def rename_dirs(dir_array)
  dir_array.each do |dir|
    new_dir = new_name(dir)
    rename(dir, new_dir) if !(new_dir.eql? dir)
    children = Dir.entries(new_dir).reject{ |e| e[0]=="."[0] }.map{ |e| e = File.join(new_dir, e) }.find_all{ |e| File.directory? e}
    rename_dirs(children)
  end
end

def rename_files(file_array)
  file_array.each do |file|
    new_file = new_name(file)
    rename(file, new_file) if !(new_file.eql? file)
  end
end  

def rename(entry, new_entry)
  puts entry
  puts new_entry
  
  system("svn rename #{quote_str(entry)} #{quote_str(new_entry)}")
  puts "-------------------------------------------------------"
end

def new_name(entry)
    new_entry = String.new entry
    RENAMES.each { |k,v| new_entry.gsub!(k, v) }
    return new_entry
end

def replace_contents(file_array)
  file_array.each do |entry|
    temp = entry + ".bak123"
    puts "replacing contents of #{entry}"

    new_contents = []
    File.open(entry) do |input|
      File.open(temp, "w") do |output|
        input.each do |line|
          new_line = String.new line
          RENAMES.each{ |orig, new| new_line.gsub!(orig, new) }
	  output << new_line
        end
      end
    end
    File.rename(temp, entry)
  end
end

def quote_str(str)
  "\"" + str + "\""
end

def get_files(dir_array)
  files = []
  dir_array.each { |dir| files.concat(Dir.glob("#{dir}/**/*").find_all{ |e| File.file? e }) }
  return files
end

def get_text_files()
 get_files.reject{ |f| NO_REPLACE_EXTS.any? { |e| e==f[-3..-1] } }
end

rename_dirs(DIRS)
rename_files(get_files(DIRS))
replace_contents(get_text_files(DIRS))
